package xyz.heyaoshare.core.service.common.impl;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import xyz.heyaoshare.common.constants.CacheKey;
import xyz.heyaoshare.config.properties.WebProperties;
import xyz.heyaoshare.core.controller.auth.vo.resp.CaptchaRespVO;
import xyz.heyaoshare.core.service.common.CaptchaService;
import xyz.heyaoshare.utils.BeanUtils;
import xyz.heyaoshare.utils.StrUtils;
import xyz.heyaoshare.utils.captcha.CaptchaBO;
import xyz.heyaoshare.utils.captcha.CaptchaUtils;

import java.util.concurrent.TimeUnit;

import static xyz.heyaoshare.exceptions.code.ErrorInfo.*;
import static xyz.heyaoshare.exceptions.customize.ServerException.exception;

/**
 * 验证码 Service 实现类
 * @author YueHe
 * @version 0.0.1
 * @since 2025/5/20 下午4:02
 */
@Slf4j
@Service
public class CaptchaServiceImpl implements CaptchaService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private WebProperties webProperties;


    @Override
    public CaptchaRespVO getCaptcha() {
        try {
            // 生成验证码
            CaptchaBO captchaBO = CaptchaUtils.generateCaptcha();
            log.info("captchaBO:{}", captchaBO);
            // 存入 Redis，设置 60s 过期
            String cacheKey = CacheKey.USER_CAPTCHA.concat(captchaBO.getKey());
            redisTemplate.opsForValue().set(cacheKey, captchaBO.getText(), webProperties.getCaptchaExpireTime(), TimeUnit.SECONDS);
            log.info("验证码已存入 Redis，key:{}", cacheKey);
            return BeanUtils.copyProperties(captchaBO, CaptchaRespVO.class);
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            throw exception(CAPTCHA_ERROR);
        }
    }

    @Override
    public void validateCaptcha(String key, String userCode) {
        // 校验参数
        if (StrUtils.isBlank(key) || StrUtils.isBlank(userCode)) throw exception(PARAM_ERROR);

        // 从 Redis 获取验证码
        String cacheKey = CacheKey.USER_CAPTCHA.concat(key);
        String expectedCode = redisTemplate.opsForValue().get(cacheKey);
        if (StrUtils.isBlank(expectedCode)) {
            log.error("验证码不存在或已失效!key:{}", key);
            throw exception(CAPTCHA_EXPIRED);
        }

        // 比较验证码
        if (!userCode.equals(expectedCode)) {
            log.error("验证码错误!user:{} = redis:{}", userCode, expectedCode);
            throw exception(CAPTCHA_CODE_ERROR);
        }

        try {
            // 验证码正确，删除 Redis 缓存
            redisTemplate.delete(cacheKey);
            log.info("验证码校验成功，已删除验证码缓存!key:{}", cacheKey);
        } catch (Exception e) {
            log.error("删除验证码缓存失败", e);
        }
    }

}